package com.workcell.workdata.xthings.service.impl.mqtt;


import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.workcell.workdata.xthings.constant.HeatExchangersDataStatusEnum;
import com.workcell.workdata.xthings.dto.CodeChainnumVo;
import com.workcell.workdata.xthings.entity.mqtt.HeatExchangersData;
import com.workcell.workdata.xthings.mapper.mqtt.HeatExchangersDataMapper;
import com.workcell.workdata.xthings.service.factory.HardwareRealDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@DS("slave_mqtt")
@RequiredArgsConstructor
public class HeatExchangersRealDataServiceImpl extends ServiceImpl<HeatExchangersDataMapper, HeatExchangersData> implements HardwareRealDataService {

	private final RedisTemplate redisTemplate;
	private final String baseCodeBaseRedisKey = "DataQrCode_Valve_DataHourLineChartInfo_%s_%s";
	private final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

	/**
	 * 获取硬件最近的一次数据
	 * @param deviceNo 设备编号
	 * @param time
	 * @return
	 */
	@Override
	public HeatExchangersData getLatelyDataInfo(String deviceNo, String manufacturerCode, Integer time) {
		HeatExchangersData heatExchangersData = setHeatExchangersDataEnum(baseMapper.getLatelyDataInfo(deviceNo, manufacturerCode, time));
		return heatExchangersData;
	}

	/**
	 * 获取硬件最近六个小时的数据：折线图
	 * @param deviceNo
	 * @return
	 */
	@Override
	public Object getDataHourLineChartInfo(String deviceNo, String manufacturerCode) {
//		Map<String, HeatExchangersData> heatExchangersDataMap = new LinkedHashMap<>(6);
//		// 获取当前小时时间
//		Date nowHourTime = DateTimeUtil.addHourAndFormatSM(0);
//		Date nowHourTimeAddOne = DateTimeUtil.addHourAndFormatSM(1);
//		checkRedisSearchDbDataChar(heatExchangersDataMap, deviceNo, manufacturerCode, nowHourTime, nowHourTimeAddOne);
//		// 处理一个小时前的数据
//		Date nowHourTimeSub1 = DateTimeUtil.addHourAndFormatSM(-1);
//		checkRedisSearchDbDataChar(heatExchangersDataMap, deviceNo, manufacturerCode, nowHourTimeSub1, nowHourTime);
//		// 处理两个小时前的数据
//		Date nowHourTimeSub2 = DateTimeUtil.addHourAndFormatSM(-2);
//		checkRedisSearchDbDataChar(heatExchangersDataMap, deviceNo, manufacturerCode, nowHourTimeSub2, nowHourTimeSub1);
//		// 处理三个小时前的数据
//		Date nowHourTimeSub3 = DateTimeUtil.addHourAndFormatSM(-3);
//		checkRedisSearchDbDataChar(heatExchangersDataMap, deviceNo, manufacturerCode, nowHourTimeSub3, nowHourTimeSub2);
//		// 处理四个小时前的数据
//		Date nowHourTimeSub4 = DateTimeUtil.addHourAndFormatSM(-4);
//		checkRedisSearchDbDataChar(heatExchangersDataMap, deviceNo, manufacturerCode, nowHourTimeSub4, nowHourTimeSub3);
//		// 处理五个小时前的数据
//		Date nowHourTimeSub5 = DateTimeUtil.addHourAndFormatSM(-5);
//		checkRedisSearchDbDataChar(heatExchangersDataMap, deviceNo, manufacturerCode, nowHourTimeSub5, nowHourTimeSub4);
//		// 组装数据
//		JSONArray typeArray = new JSONArray();
//		typeArray.add("阀门状态");
//		JSONArray timeArray = new JSONArray();
//		JSONArray informationArray = new JSONArray();
//		JSONObject deviceStatusObj = new JSONObject();
//		deviceStatusObj.put("name","阀门状态");
//		JSONArray deviceStatusArray = new JSONArray();
//		// 逆序遍历
//		ListIterator<Map.Entry<String, HeatExchangersData>> i = new ArrayList<>(heatExchangersDataMap.entrySet()).listIterator(heatExchangersDataMap.size());
//		while(i.hasPrevious()) {
//			Map.Entry<String, HeatExchangersData> entry = i.previous();
//			timeArray.add(entry.getKey());
//			deviceStatusArray.add(entry.getValue().getDeviceStatus());
//		}
//		deviceStatusObj.put("data",deviceStatusArray);
//		informationArray.add(deviceStatusObj);
//		JSONObject jsonObject = new JSONObject();
//		jsonObject.put("typeArray",typeArray);
//		jsonObject.put("timeArray",timeArray);
//		jsonObject.put("informationArray",informationArray);
		return null;
	}

	@Override
	public Page getHardwareDataInfo(CodeChainnumVo.SelectChainNumDataVo selectChainNumDataVo) {
		LambdaQueryWrapper<HeatExchangersData> queryWrapper = new QueryWrapper<HeatExchangersData>().lambda()
				.eq(ObjectUtil.isNotEmpty(selectChainNumDataVo.getDeviceNo()),HeatExchangersData::getSlaveDeviceNo,selectChainNumDataVo.getDeviceNo())
				.eq(ObjectUtil.isNotEmpty(selectChainNumDataVo.getManufacturerCode()),HeatExchangersData::getManufacturerCode,selectChainNumDataVo.getManufacturerCode())
				.and(ObjectUtil.isNotEmpty(selectChainNumDataVo.getStartTime()) || ObjectUtil.isNotEmpty(selectChainNumDataVo.getEndTime()),
						i -> i.between(HeatExchangersData::getCreateTime,selectChainNumDataVo.getStartTime(),selectChainNumDataVo.getEndTime()));

		Page<HeatExchangersData> page = new Page<>(selectChainNumDataVo.getPageNum(), selectChainNumDataVo.getPageSize());
		page.addOrder(OrderItem.desc("create_time"));
		return this.page(page,queryWrapper);
	}

	@Override
	public Object getRealData(String deviceNo) {
		LocalDateTime endTime = LocalDateTimeUtil.now();
		LocalDateTime startTime = LocalDateTimeUtil.offset(endTime, -1, ChronoUnit.MINUTES);
		LambdaQueryWrapper<HeatExchangersData> lambdaQueryWrapper = Wrappers.lambdaQuery(HeatExchangersData.class);
		lambdaQueryWrapper.eq(HeatExchangersData::getSlaveDeviceNo,deviceNo);
		lambdaQueryWrapper.between(HeatExchangersData::getCreateTime,startTime,endTime);
		lambdaQueryWrapper.orderByDesc(HeatExchangersData::getCreateTime);
		lambdaQueryWrapper.last("limit 1");

		HeatExchangersData heatExchangersData = setHeatExchangersDataEnum(this.getOne(lambdaQueryWrapper));
		return heatExchangersData;
	}

	private HeatExchangersData setHeatExchangersDataEnum(HeatExchangersData lambdaQueryWrapper) {
		HeatExchangersData heatExchangersData = lambdaQueryWrapper;
		if (ObjectUtil.isNotEmpty(heatExchangersData)) {
			heatExchangersData.setDeviceStatus(HeatExchangersDataStatusEnum.RunStatusEnum.getByCode((NumberUtil.roundStr(heatExchangersData.getDeviceStatus(), 0))).getMsg());
		}
		return heatExchangersData;
	}

	public void checkRedisSearchDbDataChar(Map<String, HeatExchangersData> heatExchangersDataMap, String deviceNo, String manufacturerCode, Date nowHourTime, Date nowHourTimeAddOne){
		Object nowHourTimeDate = redisTemplate.opsForValue().get(String.format(baseCodeBaseRedisKey,deviceNo,nowHourTime));
		if (ObjectUtil.isEmpty(nowHourTimeDate)){
			nowHourTimeDate = this.baseMapper.getDataHourLineChartInfo(deviceNo, manufacturerCode, nowHourTime, nowHourTimeAddOne);
			if (ObjectUtil.isNotEmpty(nowHourTimeDate)){
				redisTemplate.opsForValue().set(String.format(baseCodeBaseRedisKey,deviceNo,nowHourTime),nowHourTimeDate,1, TimeUnit.DAYS);
			}
		}
		heatExchangersDataMap.put(sdf.format(nowHourTime),ObjectUtil.isEmpty(nowHourTimeDate)?new HeatExchangersData():(HeatExchangersData) nowHourTimeDate);
	}

}
